package com.gable.exhibition.service.impl;

import com.gable.common.util.*;
import com.gable.exhibition.dao.*;
import com.gable.exhibition.model.*;
import com.gable.exhibition.service.UserService;
import com.gable.exhibition.util.MessageUtil;
import com.gable.exhibition.view.QueryUserTermInit;
import com.gable.exhibition.view.UserView;
import com.gable.exhibition.view.WeixinUserInfo;
import net.sf.json.JSONObject;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Lesson on 2017/12/28.
 */
@Service("userService")
public class UserServiceImpl implements UserService{

    private static final String APPID = "wx086a1257d795c3c1";
    private static final String SECRET = "3038a7de1dd702137ff03ddc7aa7f1a6";

    @Autowired
    UserDao userDao;

    @Autowired
    ValidateCodeDao validateCodeDao;

    @Autowired
    ItemDao itemDao;

    @Autowired
    HospitalDao hospitalDao;

    @Autowired
    ManufacturerDao manufacturerDao;

    @Autowired
    MaintainerDao maintainerDao;

    @Autowired
    SupplierDao supplierDao;

    @Autowired
    SysUrlDao sysUrlDao;

    @Override
    public ReturnResultUtil userLoginByWeb(UserView user) {
        UserView users = new UserView();
        if(user.getLoginType()==3){
            users = userDao.loginUserByOpenId(user.getOpenId());
//            WeixinUserInfo userInfo = this.getUserInfo(user.getAccessToken(), user.getOpenId());
//            users.setWeixinUserInfo(userInfo);
        }else{
            users = userDao.loginUser(user.getUserName());
        }
        if(users == null){
            return new ReturnResultUtil(500,MessageUtil.USERNAMEDOESNOTEXIST);
        }

        if(users.getIsDel() == 1){
            return new ReturnResultUtil(500,MessageUtil.ACCOUNTISDISABLE);
        }
        if(user.getLoginType()!=3){
            String password = MD5Util.md5(user.getPassword());
            if(!users.getPassword().equals(password)){
                return new ReturnResultUtil(500,MessageUtil.PASSWORDERROR);
            }
        }

        List<SysUrl> list =  userDao.querySysUserByLoginUser(users.getUserId());
        List<SysUrl> lists = new ArrayList<>();
        for(SysUrl sysUrl : list){
            if(sysUrl.getLevel() == 0){
                List<SysUrl> listss = new ArrayList<>();
                for(SysUrl sysUrl1 : list){
                    if(sysUrl1.getUpper() != null && sysUrl.getId().longValue() == sysUrl1.getUpper().longValue()){
                        listss.add(sysUrl1);
                    }
                }
                sysUrl.setLists(listss);
                lists.add(sysUrl);
            }
        }
        Integer loginType = user.getLoginType();
        UserView loginUser = loginUser(users);
        loginUser.setSysUrlList(lists);
        CacheData.addSessionUser( loginUser,loginType==null?2:loginType);
        return new ReturnResultUtil(200,MessageUtil.LOGINSUCCESS,loginUser);
    }

    public UserView loginUser(UserView userView){
        if(userView == null){
            return null;
        }
        String secretKey = UUIDGenerator.generate(userView.getUserId());
        UserView userView1 = new UserView();
        userView1.setUserId(userView.getUserId());
        userView1.setHospitalName(userView.getHospitalName());
        userView1.setMaintainerName(userView.getMaintainerName());
        userView1.setManufacturerName(userView.getManufacturerName());
        userView1.setHospitalId(userView.getHospitalId());
        userView1.setManufacturerId(userView.getManufacturerId());
        userView1.setMaintainerId(userView.getMaintainerId());
        userView1.setMobile(userView.getMobile());
        userView1.setStatus(userView.getStatus());
        userView1.setTag(userView.getTag());
        userView1.setRealName(userView.getRealName());
        userView1.setType(userView.getType());
        userView1.setUserName(userView.getUserName());
        userView1.setSecretKey(secretKey);
        userView1.setSupplierId(userView.getSupplierId());
        userView1.setSupplierName(userView.getSupplierName());
        userView1.setCommissionId(userView.getCommissionId());
        userView1.setCommissionName(userView.getCommissionName());
        userView1.setOpenId(userView.getOpenId());
        return userView1;
    }


    @Override
    public ReturnResultUtil userLoginByApp(UserView userView) {
        if(userView.getLoginType() == 1 || userView.getLoginType() == 3){
             return userLoginByWeb(userView);
        }else if(userView.getLoginType() == 2){
            return  userLoginByMobile(userView);
        }
        return new ReturnResultUtil(500,MessageUtil.LOGINTYPEERROR);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil updatePassword(UserView userView) {
        User user = userDao.selectByPrimaryKey(userView.getUserId());
        if(userView.getOldPassword() != null && !userView.getOldPassword() .equals("")){
            String oldPassword = MD5Util.md5(userView.getOldPassword());
            if(!user.getPassword().equals(oldPassword)){
                return new ReturnResultUtil(500,MessageUtil.OLDPASSWORDERRER);
            }
        }
        user.setPassword(MD5Util.md5(userView.getNewPassword()));
        int result = userDao.updatePassword(user);
        if(result>0){
            return new ReturnResultUtil(200,MessageUtil.UPDATEPASSWORDSUCCESS);
        }
        return new ReturnResultUtil(200,MessageUtil.UPDATEPASSWORDERROR);
    }

    @Override
    public ReturnResultUtil queryUserTermInit(Map map) {
        QueryUserTermInit init = new QueryUserTermInit();
        List<Item> itemList = itemDao.queryItem(map);
        for(Item item : itemList){
            item.setItem(item.getItem() + "[" + ChineseToEnglish.getPinYinHeadChar(item.getItem())+"]");
        }
        init.setItemList(itemList);

        List<Hospital>  hospitalsList = hospitalDao.queryHospitalListBySelect(null);
        for (Hospital hospital : hospitalsList){
            hospital.setHospitalName(hospital.getHospitalName() + "[" + ChineseToEnglish.getPinYinHeadChar(hospital.getHospitalName()) + "]");
        }
        init.setHospitalList(hospitalsList);

        List<Manufacturer> manufacturerList = manufacturerDao.queryManufacturer(null);
        for (Manufacturer manufacturer : manufacturerList){
            manufacturer.setManufacturerName(manufacturer.getManufacturerName() + "[" + ChineseToEnglish.getPinYinHeadChar(manufacturer.getManufacturerName()) + "]");
        }
        init.setManufacturerList(manufacturerList);

        List<Maintainer> maintainerList = maintainerDao.queryMaintainer();
        for (Maintainer maintainer : maintainerList){
            maintainer.setMaintainerName(maintainer.getMaintainerName() + "[" + ChineseToEnglish.getPinYinHeadChar(maintainer.getMaintainerName()) + "]");
        }
        init.setMaintainerList(maintainerList);

        List<Supplier> supplierList = supplierDao.querySupplier(null);
        for(Supplier supplier : supplierList){
            supplier.setSupplierName(supplier.getSupplierName() + "["+ChineseToEnglish.getPinYinHeadChar(supplier.getSupplierName())+"]");
        }
        init.setSupplierList(supplierList);
        return new ReturnResultUtil(200,MessageUtil.QUERYSUCCESS,init);
    }

    @Override
    public ReturnResultUtil queryUserList(UserView userView) {
        int count = userDao.queryUserCount(userView);
        List<UserView> list = userDao.queryUserList(userView);
        UserView userView1 = new UserView();
        userView1.setCount(count);
        userView1.setList(list);
        return new ReturnResultUtil(200,MessageUtil.QUERYSUCCESS,userView1);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil addOrUpdateUser(UserView userView) {
        int count = userDao.checkUserExitis(userView);
        if(count > 0){
            return new ReturnResultUtil(500,MessageUtil.USERNAMEDOESTEXIST);
        }
        int counts = userDao.checkUserMobileExitis(userView);
        if(counts > 0){
            return new ReturnResultUtil(500,MessageUtil.MOBILEEXITIS);
        }
        if(userView.getPassword() != null){
            userView.setPassword(MD5Util.md5(userView.getPassword()));
        }
        int result = 0;
        if(userView.getUserId() == null){
            userView.setUserId(UUIDGenerator.getUniqueLong());
            result = userDao.insertSelective(userView);
        }else{
            userView.setPassword(null);
            result = userDao.updateByPrimaryKeySelective(userView);
        }
        if(result > 0){
            return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS);
        }
        return  new ReturnResultUtil(500,MessageUtil.SAVEFAIL);
    }

    @Override
    public ReturnResultUtil queryUserInfo(Long userId) {
        UserView userView = userDao.queryUserInfo(userId);
        return new ReturnResultUtil(200,MessageUtil.QUERYSUCCESS,userView) ;
    }

    @Override
    public ReturnResultUtil queryUser(UserView userView) {
        User user = userDao.queryUser(userView);
        return new ReturnResultUtil(200,MessageUtil.QUERYSUCCESS,user) ;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil queryUserByEngineerPhone(String engineerPhone,String engineerName, Long serviceId,Long serviceType) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        User user= new User();
        user.setMobile(engineerPhone);
        //user.setMaintainerId(serviceId);
        User user1 = userDao.checkUserByEngineerPhone(user);

        /*if(user1 != null ){
            Integer maintainerId = user1.getMaintainerId()==null?0:user1.getMaintainerId().intValue();
            if(maintainerId!= serviceId.intValue())
                return new ReturnResultUtil(500,MessageUtil.MOBILEEXIST);
        }*/
        if(user1 == null) {
            user1 = new User();
            user1.setUserId(UUIDGenerator.getUniqueLong());
            //user1.setMaintainerId(serviceId);
            user1.setUserName(engineerPhone);
            if(serviceType == null){
                return null;
            }
            if(serviceType.longValue() == 1102){
                user1.setManufacturerId(serviceId);
                user1.setTag(1004L);
            }else if(serviceType.longValue() == 1103){
                user1.setMaintainerId(serviceId);
                user1.setTag(1006L);
            }else if(serviceType.longValue() == 1105){
                user1.setSupplierId(serviceId);
                user1.setTag(1009L);
            }else if(serviceType.longValue() == 1101){
                user1.setHospitalId(serviceId);
                user1.setTag(1002L);
            }else{
                return null;
            }
            user1.setType(serviceType);
            user1.setMobile(engineerPhone);
            user1.setRealName(engineerName);
            user1.setIsDel(0);
            user1.setCreateTime(sdf.format(new Date()));
            user1.setRemark("流程数据产生");
            userDao.insertSelective(user1);
        }else{
            //判断该用户是否属于厂家工程师、维修商工程师、供应商工程师的一种
            if(user1.getTag().longValue()!=1004 && user1.getTag().longValue()!=1006 && user1.getTag().longValue()!=1009){
                return new ReturnResultUtil(500,MessageUtil.USERINPUTERROR);
            }
        }
        return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS,user1);
    }

    /**
     * 手机号码登录
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil userLoginByMobile(UserView userView){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        ValidateCode validateCode = new ValidateCode();
        validateCode.setMobile(userView.getUserName());
        validateCode.setCode(userView.getCode());
        ValidateCode vc = validateCodeDao.verificationCode(validateCode);
        if(vc == null){
            return new ReturnResultUtil(500,MessageUtil.MOBILEORCODEERROR);
        }
        Date date1 = new Date();
        try {
            date1 = sdf.parse(vc.getCreateTime());
        }catch (Exception e){
            e.printStackTrace();
        }
        Date date2 = new Date();
        if((date2.getTime() - date1.getTime()) > 300000){
            return  new ReturnResultUtil(500,MessageUtil.VERIFICATIONCODETIMEOUT);
        }
        UserView users = userDao.loginUser(userView.getUserName());
        if(users != null){
            if(users.getIsDel() == 1){
                return new ReturnResultUtil(500,MessageUtil.ACCOUNTISDISABLE);
            }
            UserView loginUser = loginUser(users);
            CacheData.addSessionUser((UserView) loginUser,1);
            if(StringUtil.isEmpty(users.getPassword())){
                loginUser.setStatus(100);
            }
            return new ReturnResultUtil(200,MessageUtil.LOGINSUCCESS,loginUser);
        }

        return new ReturnResultUtil(200,MessageUtil.LOGINSUCCESS);

    }


    //修改用户上次登录时间，是否小程序登录
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void  updateUserLastLoginTime(Long userId,Boolean bl){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        User user = new User();
        user.setUserId(userId);
        user.setLastLoginTime(df.format(new Date()));
        user.setLoginWechat(bl);
        userDao.updateByPrimaryKeySelective(user);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil completionUserInfo(UserView user) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int count = userDao.checkUserExitis(user);
        if(count > 0){
            return new ReturnResultUtil(500,MessageUtil.USERNAMEDOESTEXIST);
        }
        if(user.getPassword() != null){
            user.setPassword(MD5Util.md5(user.getPassword()));
        }
        int counts = userDao.checkUserMobileExitis(user);
        if(counts > 0){
            return new ReturnResultUtil(500,MessageUtil.MOBILEEXITIS);
        }

        user.setIsDel(0);
        user.setLastLoginTime(df.format(new Date()));
        user.setLoginWechat(true);
        user.setPyName(user.getUserName());
        user.setCreateTime(df.format(new Date()));
        int result = 0;
        user.setUserId(UUIDGenerator.getUniqueLong());
        user.setSecretKey(UUIDGenerator.getUniqueNumber());
        result = userDao.insertSelective(user);
        if(result > 0){
            UserView uv = userDao.queryUserInfo(user.getUserId());
            UserView loginUser = loginUser(uv);
            CacheData.addSessionUser(loginUser,1);
            return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS,loginUser);
        }

        return new ReturnResultUtil(500,MessageUtil.SAVEFAIL);
    }

    @Override
    public ReturnResultUtil updateRealName(UserView userView) {
        int count = userDao.updateByPrimaryKeySelective(userView);
        if(count>0){
            return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS);
        }
        return new ReturnResultUtil(500,MessageUtil.SAVEFAIL);
    }

    @Override
    public ReturnResultUtil getOpenId(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+APPID+
                "&secret="+SECRET+"&js_code="+ code +"&grant_type=client_credential";
        HttpClient client = null;
        Map<String,Object> result =new HashMap<String,Object>();
        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(url);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject OpenidJSONO=JSONObject.fromObject(response);
            String accessToken=String.valueOf(OpenidJSONO.get("access_token"));
            String openId = String.valueOf(OpenidJSONO.get("openid"));
            String key = DateUtils.createID();
            InitDataUitl.openIdMap.put(key,openId);

            result.put("openId",openId);
            result.put("accessToken",accessToken);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return new ReturnResultUtil(200,MessageUtil.QUERYSUCCESS,result);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ReturnResultUtil updateOpenId(UserView userView) {
        //先解除绑定
        UserView uv = userDao.loginUserByOpenId(userView.getOpenId());
        if(uv!=null){
            userDao.updateOpenIdNull(uv);
        }

        int result = userDao.updateOpenId(userView);
        if(result>0){
            UserView user = CacheData.getSessionUser(userView.getUserId(),1);
            user.setOpenId(userView.getOpenId());
            return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS,user);
        }
        return new ReturnResultUtil(200,MessageUtil.SAVEFAIL);
    }

    public  WeixinUserInfo getUserInfo(String accessToken, String openId) {

        Logger log = LoggerFactory.getLogger(HttpUtil.class);
        WeixinUserInfo weixinUserInfo = null;
        // 拼接请求地址
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        // 获取用户信息
        JSONObject jsonObject = HttpUtil.httpsRequest(requestUrl, "GET", null);

        if (null != jsonObject) {
            try {
                weixinUserInfo = new WeixinUserInfo();
                // 用户的标识
                weixinUserInfo.setOpenId(jsonObject.getString("openid"));
                // 昵称
                weixinUserInfo.setNickname(jsonObject.getString("nickname"));
                // 用户的性别（1是男性，2是女性，0是未知）
                weixinUserInfo.setSex(jsonObject.getInt("sex"));
                // 用户所在国家
                weixinUserInfo.setCountry(jsonObject.getString("country"));
                // 用户所在省份
                weixinUserInfo.setProvince(jsonObject.getString("province"));
                // 用户所在城市
                weixinUserInfo.setCity(jsonObject.getString("city"));
                // 用户头像
                weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
            } catch (Exception e) {
                if (0 == weixinUserInfo.getSubscribe())
                    log.error("用户{}已取消关注", weixinUserInfo.getOpenId());
                else {
                    int errorCode = jsonObject.getInt("errcode");
                    String errorMsg = jsonObject.getString("errmsg");
                    log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode,errorMsg);
                }
            }
        }
        return weixinUserInfo;
    }

    @Override
    public ReturnResultUtil querySysUrl(Long userId) {
        List<SysUrl> list = sysUrlDao.querySysUrl(userId);
        return new ReturnResultUtil(200, MessageUtil.QUERYSUCCESS,list);
    }

    @Override
    public ReturnResultUtil saveSetMenu(Long userId, List<Long> urlIdList) {
        //删除当前用户绑定的菜单
        userDao.deleteMenuByUserId(userId);
        //重新添加用户和菜单的关联关系
        for(Long urlId : urlIdList){
            userDao.insertUserMenu(userId,urlId);
        }
        return new ReturnResultUtil(200,MessageUtil.SAVESUCCESS);
    }


}
